/*
* Copyright (C) 2014 MillerV
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package aspect.example;
import static aspect.core.AspectRenderer.*;
import aspect.core.CameraViewpoint;
import aspect.physics.Time;
import aspect.render.Light;
import aspect.render.Material;
import aspect.render.Mesh;
import aspect.render.Texture;
import aspect.render.shader.Shader;
import aspect.render.shader.ShaderProgram;
import static aspect.resources.Resources.*;
import aspect.util.Vector2;
import aspect.util.Vector3;
import java.nio.FloatBuffer;
import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import static org.lwjgl.opengl.EXTFramebufferObject.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL14.GL_DEPTH_COMPONENT24;
import org.lwjgl.util.glu.GLU;
/**
*
* @author MillerV
*/
public class FrameBufferShip extends Texture {
public final int fboID;
private final int depthID;
public final Mesh drawModel;
public PlayerShip viewpoint;
private ShaderProgram postProcess;
public FrameBufferShip(int width, int height, PlayerShip viewpoint) throws LWJGLException {
super(GL_TEXTURE_2D, glGenTextures());
if (!FBO_ENABLED) {
throw new LWJGLException("FBO is not supported on your version of OpenGL");
}
fboID = glGenFramebuffersEXT();
depthID = glGenRenderbuffersEXT();
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboID);
bind();
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_INT, (java.nio.ByteBuffer) null);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, id, 0);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthID);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, width, height);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depthID);
this.width = width;
this.height = height;
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
drawModel = (Mesh)rect(new Material(this), getCanvasWidth(), getCanvasHeight());
this.viewpoint = viewpoint;
}
public void postProcess(ShaderProgram shader) {
postProcess = shader;
drawModel.material.shader = postProcess;
postProcess.setVar("width", (float) getCanvasWidth());
postProcess.setVar("height", (float) getCanvasHeight());
}
public void update() {
postProcess.setVar("time", Time.frameTime());
if (Display.wasResized()) {
postProcess.setVar("width", (float) getCanvasWidth());
postProcess.setVar("height", (float) getCanvasHeight());
}
}
public void capture() {
glViewport(0, 0, width, height);
FloatBuffer pt = BufferUtils.createFloatBuffer(4);
Vector3 pos = Light.lights[0].pos;
GLU.gluProject(pos.x, pos.y, pos.z, modelViewMatrix().getBuffer(), projectionMatrix().getBuffer(), viewport(), pt);
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboID);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
viewpoint.cam();
}
public void stop() {
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, getCanvasWidth(), getCanvasHeight());
}
public void render() {
setRenderMode(RenderMode.ORTHOGONAL);
loadIdentity();
translate(new Vector2(getCanvasWidth() / 2, getCanvasHeight() / 2));
drawModel.render();
}
}